/* ---------------------------------------------------------------------------------------------
 *
 *            Capital Alliance Software Confidential Proprietary
 *            (c) Copyright CAS 201{x}, All Rights Reserved
 *                          www.pekall.com
 *
 * ----------------------------------------------------------------------------------------------
 */

package com.pekall.myDictionary.screens;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteOrder;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewSwitcher;
import android.widget.AdapterView.OnItemClickListener;

import com.pekall.myDictionary.utils.ChineseCompare;
import com.pekall.myDictionary.utils.PekalletcHead;
import com.pekall.myDictionary.utils.SQLiteHistory;

public class HomeScreen extends Activity implements OnItemClickListener, OnClickListener,
        TextWatcher {

    private final static String TAG = HomeScreen.class.getSimpleName();

    private SQLiteHistory mSQL;

    // 定义一个对话框的ID
    int Edward_Movie_Dialog = 1;

    AlertDialog dialog;

    /* ================== Activity ======================== */

    boolean mBigEndian;

    private ViewSwitcher mViewSwitcher;

    private ListView mListView;

    private EditText mEdit;

    private ImageButton mSearchBtn;

    ChineseCompare ts = new ChineseCompare();

    // private ShareUtil mShareUtil;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        setContentView(R.layout.main);
        // mShareUtil = new ShareUtil(this);
        mBigEndian = (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN);
        mViewSwitcher = (ViewSwitcher) findViewById(R.id.switcher_loading);
        mListView = (ListView) findViewById(R.id.wordlist);
        mListView.setOnItemClickListener(this);
        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        mEdit = (EditText) findViewById(R.id.input);
        mSearchBtn = (ImageButton) findViewById(R.id.searchBtn);
        mSearchBtn.setOnClickListener(this);
        setProgressBarIndeterminateVisibility(false);
        new initDictDataTask().execute((Void) null);
    }

    /* ================== Adapter ======================== */
    private LayoutInflater mFactory;

    private int mWordCount = 0;

    private int mBlockCount;

    private int mBlockIndex;

    private String[] mCurrentBlock;

    private int[] mIndex;

    private int mBlockLength;

    private RandomAccessFile mFile;

    private int mBlockOffset;

    class WordAdapter extends BaseAdapter {

        WordAdapter(Context context) {
            mFactory = LayoutInflater.from(context);
        }

        public int getCount() {
            return mWordCount;
        }

        public Object getItem(int position) {
            return null;
        }

        public long getItemId(int position) {
            return 0;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;
            if (v == null) {
                v = mFactory.inflate(android.R.layout.simple_list_item_1, parent, false);
            }
            if (position / mBlockCount != mBlockIndex) {
                getWordBlock(position / mBlockCount);
            }

            TextView tv = (TextView) v.findViewById(android.R.id.text1);
            String word = mCurrentBlock[position % mBlockCount];

            int n = word.indexOf('\t');
            if (n > 0) {
                tv.setText(word.substring(0, n));
            }
            return v;
        }

    }

    /**
     * 获取单词所在块
     * 
     * @param index
     */
    void getWordBlock(int index) {
        if (index >= mIndex.length)
            return;
        int endOffset = (index == mIndex.length - 1) ? mBlockLength : mIndex[index + 1];
        try {
            byte[] wordBlockRaw = new byte[endOffset - mIndex[index]];
            mFile.seek(mBlockOffset + mIndex[index]);
            mFile.read(wordBlockRaw);
            int count = 0;
            for (int i = 0; i < wordBlockRaw.length; i++) {
                if (wordBlockRaw[i] == 0)
                    count++;
            }
            mCurrentBlock = new String[count];
            BuildWordArray(mCurrentBlock, wordBlockRaw);
            wordBlockRaw = null;
            mBlockIndex = index;
        } catch (IOException e) {
        }
    }

    /* ================== adapter cte ======================== */
    class WordAdapterCte extends BaseAdapter {

        WordAdapterCte(Context context) {
            mFactoryCte = LayoutInflater.from(context);
        }

        public int getCount() {
            return mWordCountCte;
        }

        public Object getItem(int position) {
            return null;
        }

        public long getItemId(int position) {
            return 0;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;
            if (v == null) {
                v = mFactoryCte.inflate(android.R.layout.simple_list_item_1, parent, false);
            }
            if (position / mBlockCountCte != mBlockIndexCte) {
                getWordBlockCte(position / mBlockCountCte);
            }

            TextView tv = (TextView) v.findViewById(android.R.id.text1);
            // tv.setLayoutParams(new Gallery.LayoutParams(100, 100));

            String word = mCurrentBlockCte[position % mBlockCountCte];

            int n = word.indexOf('\t');
            if (n > 0) {
                tv.setText(word.substring(0, n));
            }
            return v;
        }

    }

    /* ======================= InitDictDataTask ======================== */
    private WordAdapter mAdapter;

    private WordAdapterCte mAdapterCte;

    private boolean isCnOrEn = false;

    // private volatile boolean mLoading;

    private class initDictDataTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            initDictData();
            initDictDataCte();
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            setProgressBarIndeterminateVisibility(false);

            mAdapter = new WordAdapter(HomeScreen.this);
            mAdapterCte = new WordAdapterCte(HomeScreen.this);

            mEdit.addTextChangedListener(HomeScreen.this);
            String str = mEdit.getText().toString();
            /**
             * 这里先根据字节与字符长度是否相等判断 中文，具体方法以后实现
             */
            if (str.getBytes().length == str.length()) {
                mListView.setAdapter(mAdapter);
                getWordSuggest(str);
            } else {
                isCnOrEn = true;
                mListView.setAdapter(mAdapterCte);
                getWordSuggestCte(str);
            }
            mViewSwitcher.setDisplayedChild(1);
            // dialog.cancel();
        }

        @Override
        protected void onPreExecute() {
            setProgressBarIndeterminateVisibility(true);
            mViewSwitcher.setDisplayedChild(0);
            // dialog.show();
        }

    }

    /* ======================= ETC ======================== */
    private String[] mHeadWords;

    private String[] mTailWords;

    void initDictData() {
        try {
            mFile = new RandomAccessFile(PekalletcHead.DICT_DATA_NAME, "r");
            int[] head = readDictHead();
            Log.d(TAG, head.toString());
            if (head == null)
                return;
            int count = head[PekalletcHead.HEAD_INDEX_COUNT];
            byte[] index = new byte[count * 4];
            mFile.seek(head[PekalletcHead.HEAD_INDEX_OFFSET]);
            mFile.read(index);
            mIndex = new int[count];
            for (int i = 0; i < count; i++) {
                mIndex[i] = getInt(index, 4 * i);
            }
            byte[] headWordsRaw = new byte[head[PekalletcHead.HEAD_HEADWORD_LEN]];
            mFile.seek(head[PekalletcHead.HEAD_HEADWORD_OFFSET]);
            mFile.read(headWordsRaw);
            mHeadWords = new String[count];
            BuildWordArray(mHeadWords, headWordsRaw);
            byte[] tailWordsRaw = new byte[head[PekalletcHead.HEAD_TAILWORD_LEN]];
            mFile.seek(head[PekalletcHead.HEAD_TAILWORD_OFFSET]);
            mFile.read(tailWordsRaw);
            mTailWords = new String[count];
            BuildWordArray(mTailWords, tailWordsRaw);
            mBlockOffset = head[PekalletcHead.HEAD_WORDBLOCK_OFFSET];
            mBlockLength = head[PekalletcHead.HEAD_WORDBLOCK_LEN];
            mBlockCount = head[PekalletcHead.HEAD_WORDBLOCK_COUNT];
            mWordCount = head[PekalletcHead.HEAD_WORD_COUNT];
            index = null;
            headWordsRaw = null;
            tailWordsRaw = null;
            getWordBlock(0);
        } catch (FileNotFoundException e) {
            Log.e(TAG, "File not found", e);
        } catch (IOException e) {
            Log.e(TAG, "IOE", e);
        }
    }

    /**
     * 读取dic文件head部分数据
     * 
     * @return
     */
    int[] readDictHead() {
        try {
            int[] head = new int[PekalletcHead.HEAD_SIZE];
            byte[] buffer = new byte[head.length * 4];
            mFile.seek(0);
            mFile.read(buffer);
            for (int i = 0; i < head.length; i++) {

                head[i] = getInt(buffer, i * 4);
            }
            Log.d(TAG, head.toString());
            buffer = null;
            return head;
        } catch (IOException e) {
            Log.e(TAG, "readDIctHead error", e);
            return null;
        }
    }

    /**
     * 根据传入字符串s 搜寻接近单词 ---> initDictDataTask
     * 
     * @param s
     */
    private void getWordSuggest(CharSequence s) {
        Log.d(TAG, "[onTextChanged]word is -- " + s.toString());
        /* 获取单词所在block索引 */
        int n = getWordBlockIndex(s.toString());
        Log.d(TAG, "[onTextChanged]block index -- " + n);
        if (n > -1) {
            getWordBlock(n);
            /* 获取单词在block的索引 */
            int index = getIndexInWordBlock(s.toString());
            Log.d(TAG, "index in block -- " + index);
            index = n * mBlockCount + index;
            Log.d(TAG, "position in list -- " + index);
            mListView.setSelection(index);
        }
    }

    private int getWordBlockIndex(String word) {
        return binarySearchBlock(mHeadWords, mTailWords, word);
    }

    private int getIndexInWordBlock(String word) {
        return binarySearchWordInBlock(mCurrentBlock, word);
    }

    /**
     * Search which block may contain word key 搜寻需要进入那一个block
     * 
     * @param headWords
     * @param tailWords
     * @param key
     * @return block index
     */
    private static int binarySearchBlock(String[] headWords, String[] tailWords, String key) {
        if (headWords.length != tailWords.length)
            throw new IllegalArgumentException();
        int low = 0;
        int high = headWords.length - 1;
        int mid;
        /* 二分查找 */
        while (low <= high) {
            mid = low + (high - low) / 2;
            String midHead = headWords[mid];
            String midTail = tailWords[mid];
            if (key.compareToIgnoreCase(midTail) > 0)
                low = mid + 1;
            else if (key.compareToIgnoreCase(midHead) < 0)
                high = mid - 1;
            else
                return mid;
        }
        return low;
    }

    /**
     * Search word key in block 搜寻word在block中的key
     * 
     * @param wordsInBlock
     * @param key
     * @return index
     */
    private static int binarySearchWordInBlock(String[] wordsInBlock, String key) {
        int low = 0;
        int high = wordsInBlock.length - 1;
        int keyLen = key.length();
        while (low <= high) {
            int mid = low + (high - low) / 2;
            String word = wordsInBlock[mid];
            int result = compareWordIgnoreCase(word, getWordLen(word), key, keyLen);
            if (result == 0)
                return mid;
            else if (result < 0)
                low = mid + 1;
            else
                high = mid - 1;
        }
        return low;
    }

    private static int getWordLen(String word) {
        int n = word.indexOf('\t');
        return (n > 0) ? n : word.length();
    }

    /**
     * 忽略大小写 单词比较
     * 
     * @param word1
     * @param len1
     * @param word2
     * @param len2
     * @return
     */
    public static int compareWordIgnoreCase(String word1, int len1, String word2, int len2) {
        // change to lower case
        String word1Low = word1.toLowerCase();
        String word2Low = word2.toLowerCase();
        int len = len1 < len2 ? len1 : len2;
        for (int i = 0; i < len; i++) {
            int n = word1Low.charAt(i) - word2Low.charAt(i);
            if (n != 0)
                return n;
        }
        return len1 - len2;
    }

    /* ========================= CTE =============================== */
    private LayoutInflater mFactoryCte;

    private int mWordCountCte = 0;

    private int mBlockCountCte;

    private int mBlockIndexCte;

    private String[] mCurrentBlockCte = null;

    private int[] mIndexCte;

    private int mBlockLengthCte;

    private RandomAccessFile mFileCte;

    private int mBlockOffsetCte;

    private String[] mHeadWordsCte;

    private String[] mTailWordsCte;

    void initDictDataCte() {
        try {
            mFileCte = new RandomAccessFile(PekalletcHead.DICT_DATA_CTE, "r");
            int[] head = readDictHeadCte();
            if (head == null)
                return;
            int count = head[PekalletcHead.HEAD_INDEX_COUNT];
            byte[] index = new byte[count * 4];
            mFileCte.seek(head[PekalletcHead.HEAD_INDEX_OFFSET]);
            mFileCte.read(index);
            mIndexCte = new int[count];
            for (int i = 0; i < count; i++) {
                mIndexCte[i] = getInt(index, 4 * i);
            }
            byte[] headWordsRaw = new byte[head[PekalletcHead.HEAD_HEADWORD_LEN]];
            mFileCte.seek(head[PekalletcHead.HEAD_HEADWORD_OFFSET]);
            mFileCte.read(headWordsRaw);
            mHeadWordsCte = new String[count];
            BuildWordArray(mHeadWordsCte, headWordsRaw);
            byte[] tailWordsRaw = new byte[head[PekalletcHead.HEAD_TAILWORD_LEN]];
            mFileCte.seek(head[PekalletcHead.HEAD_TAILWORD_OFFSET]);
            mFileCte.read(tailWordsRaw);
            mTailWordsCte = new String[count];
            BuildWordArray(mTailWordsCte, tailWordsRaw);
            mBlockOffsetCte = head[PekalletcHead.HEAD_WORDBLOCK_OFFSET];
            mBlockLengthCte = head[PekalletcHead.HEAD_WORDBLOCK_LEN];
            mBlockCountCte = head[PekalletcHead.HEAD_WORDBLOCK_COUNT];
            mWordCountCte = head[PekalletcHead.HEAD_WORD_COUNT];
            index = null;
            headWordsRaw = null;
            tailWordsRaw = null;
            getWordBlockCte(0);
        } catch (FileNotFoundException e) {
            Log.e(TAG, "File not found", e);
        } catch (IOException e) {
            Log.e(TAG, "IOE", e);
        }
    }

    /**
     * 读取dic文件head部分数据
     * 
     * @return
     */
    int[] readDictHeadCte() {
        try {
            int[] head = new int[PekalletcHead.HEAD_SIZE];
            byte[] buffer = new byte[head.length * 4];
            mFileCte.seek(0);
            mFileCte.read(buffer);
            for (int i = 0; i < head.length; i++) {

                head[i] = getInt(buffer, i * 4);
            }
            buffer = null;
            return head;
        } catch (IOException e) {
            Log.e(TAG, "readDIctHead error", e);
            return null;
        }
    }

    /**
     * 根据传入字符串s 搜寻接近单词 ---> initDictDataTask
     * 
     * @param s
     */
    private void getWordSuggestCte(CharSequence s) {
        Log.d(TAG, "[onTextChanged]word is -- " + s.toString());
        /* 获取单词所在block索引 */
        int n = getWordBlockIndexCte(s.toString());
        Log.d(TAG, "[onTextChanged]block index -- " + n);
        if (n > -1) {
            getWordBlockCte(n);
            /* 获取单词在block的索引 */
            int index = getIndexInWordBlockCte(s.toString());
            Log.d(TAG, "index in block -- " + index);
            index = n * mBlockCountCte + index;
            Log.d(TAG, "position in list -- " + index);
            mListView.setSelection(index);
        }
    }

    private int getWordBlockIndexCte(String word) {
        return binarySearchBlockCte(mHeadWordsCte, mTailWordsCte, word);
    }

    private int getIndexInWordBlockCte(String word) {
        return binarySearchWordInBlockCte(mCurrentBlockCte, word);
    }

    /**
     * Search which block may contain word key 搜寻需要进入那一个block
     * 
     * @param headWords
     * @param tailWords
     * @param key
     * @return block index
     */
    private int binarySearchBlockCte(String[] headWords, String[] tailWords, String key) {
        if (headWords.length != tailWords.length)
            throw new IllegalArgumentException();
        int low = 0;
        int high = headWords.length - 1;
        int mid;
        /* 二分查找 */
        while (low <= high) {
            mid = low + (high - low) / 2;
            String midHead = headWords[mid];
            String midTail = tailWords[mid];
            if (ts.compare(key, midHead) > 0)
                low = mid + 1;
            else if (ts.compare(key, midTail) < 0)
                high = mid - 1;
            else
                return mid;
        }
        return low - 1;
    }

    /**
     * Search word key in block 搜寻word在block中的key
     * 
     * @param wordsInBlock
     * @param key
     * @return index
     */
    private int binarySearchWordInBlockCte(String[] wordsInBlock, String key) {
        int low = 0;
        int high = wordsInBlock.length - 1;
        while (low <= high) {
            int mid = low + (high - low) / 2;
            String word = wordsInBlock[mid];
            int result = ts.compare(word, key);
            if (result == 0)
                return mid;
            else if (result < 0)
                low = mid + 1;
            else
                high = mid - 1;

        }
        return low;
    }

    void getWordBlockCte(int index) {
        if (index >= mIndexCte.length)
            return;
        int endOffset = (index == mIndexCte.length - 1) ? mBlockLengthCte : mIndexCte[index + 1];
        try {
            byte[] wordBlockRaw = new byte[endOffset - mIndexCte[index]];
            mFileCte.seek(mBlockOffsetCte + mIndexCte[index]);
            mFileCte.read(wordBlockRaw);
            int count = 0;
            for (int i = 0; i < wordBlockRaw.length; i++) {
                if (wordBlockRaw[i] == 0)
                    count++;
            }
            mCurrentBlockCte = new String[count];
            BuildWordArray(mCurrentBlockCte, wordBlockRaw);
            wordBlockRaw = null;
            mBlockIndexCte = index;
        } catch (IOException e) {
        }
    }

    /* ================================ Public Method====================== */
    /**
     * Java中的一个byte，其范围是-128~127的， 而Integer.toHexString的参数本来是int，
     * 如果不进行&0xff，那么当一个byte会转换成int时， 对于负数，会做位扩展，举例来说，
     * 一个byte的-1（即0xff），会被转换成int的-1（即 0xffffffff）
     * 
     * @param buffer
     * @param index
     * @return mBigdian--
     */
    int getInt(byte[] buffer, int index) {
        if (mBigEndian) {
            return ((buffer[index] & 0xff) << 24) + ((buffer[index + 1] & 0xff) << 16)
                    + ((buffer[index + 2] & 0xff) << 8) + (buffer[index + 3] & 0xff);
        } else {
            return ((buffer[index] & 0xff)) + ((buffer[index + 1] & 0xff) << 8)
                    + ((buffer[index + 2] & 0xff) << 16) + ((buffer[index + 3] & 0xff) << 24);
        }
    }

    /**
     * 生成单词数组
     * 
     * @param words
     * @param block
     */
    void BuildWordArray(String words[], byte[] block) {
        int wordBegin = 0;
        for (int i = 0; i < words.length; i++) {
            int wordEnd;
            for (wordEnd = wordBegin; wordEnd < block.length; wordEnd++) {
                // separate word with char '\0'
                if (block[wordEnd] == 0)
                    break;
            }
            try {
                words[i] = new String(block, wordBegin, wordEnd - wordBegin, "gbk");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            wordBegin = wordEnd + 1;
        }
    }

    private void saveHistory(String word) {
        mSQL = new SQLiteHistory(this);
        mSQL.save(word);
        mSQL.close();
    }

    /* ============================== Override ========================= */
    private volatile boolean mLoading;

    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        String word;
        /**
         * 判断输入中文英文
         */
        if (!isCnOrEn) {
            if (position / mBlockCount != mBlockIndex) {
                getWordBlock(position / mBlockCount);
            }
            word = mCurrentBlock[position % mBlockCount];
        } else {
            if (position / mBlockCountCte != mBlockIndexCte) {
                getWordBlockCte(position / mBlockCountCte);
            }
            word = mCurrentBlockCte[position % mBlockCountCte];
        }
        saveHistory(word);
        Intent intent = new Intent(this, ExplainScreen.class);
        intent.setData(Uri.parse(word));
        intent.putExtra("isCnOrEn", isCnOrEn);
        startActivity(intent);
        /** activity切换动画 **/
        overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
    }

    public void onClick(View v) {

        if (mSearchBtn == v) {
            if (mLoading) {
                showLoadingTips();
                return;
            }
            String s = mEdit.getText().toString();
            if (!TextUtils.isEmpty(s)) {

                /**
                 * test输入为中文
                 */
                if (!isCnOrEn) {
                    int n = getWordBlockIndex(s.toString());
                    if (n > -1) {
                        getWordBlock(n);
                        int index = getIndexInWordBlock(s.toString());
                        Log.d(TAG, "[onClick] index -- " + index + " mCurrentBlock.length -- "
                                + mCurrentBlock.length);
                        /**
                         * If the word can not be found in current block(such as
                         * bigger than the last word in dict table), set index
                         * point to the last word in current block
                         * 如果单词不存在，adapter index至block的最后一个word
                         */
                        if (index >= mCurrentBlock.length)
                            index = mCurrentBlock.length - 1;
                        String word = mCurrentBlock[index];
                        int wordEnd = word.indexOf('\t');
                        boolean isMatchWordExact = false;
                        if (wordEnd > 0) {
                            // 不区分大小写判断是否equal（‘ABC’==‘abc’）
                            isMatchWordExact = s.equalsIgnoreCase(word.substring(0, wordEnd));
                        }
                        Intent intent = new Intent(this, ExplainScreen.class);
                        if (isMatchWordExact) {
                            // 存在word，返回数据
                            intent.setData(Uri.parse(word));
                            saveHistory(word);

                        } else {
                            // 不存在，将s传给ExpalinActivity
                            intent.putExtra("key", s);
                        }
                        intent.putExtra("isCnOrEn", isCnOrEn);
                        startActivity(intent);
                        /** 动画切换 **/
                        overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
                    }
                }

                else {
                    int n = getWordBlockIndexCte(s.toString());
                    if (n > -1) {
                        getWordBlockCte(n);
                        int index = getIndexInWordBlockCte(s.toString());
                        if (index >= mCurrentBlockCte.length)
                            index = mCurrentBlockCte.length - 1;
                        String word = mCurrentBlockCte[index];
                        int wordEnd = word.indexOf('\t');
                        boolean isMatchWordExact = false;
                        if (wordEnd > 0) {
                            isMatchWordExact = s.equalsIgnoreCase(word.substring(0, wordEnd));
                        }
                        Intent intent = new Intent(this, ExplainScreen.class);
                        if (isMatchWordExact) {
                            intent.setData(Uri.parse(word));
                            saveHistory(word);
                        } else {
                            intent.putExtra("key", s);
                        }
                        startActivity(intent);
                        overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
                    }

                }
            }

        }

    }

    private void showLoadingTips() {
        Log.d(TAG, "loading in progress, please wait");
        Toast.makeText(this, R.string.toast_loading_dict_data, Toast.LENGTH_SHORT).show();
    }

    public void afterTextChanged(Editable s) {
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (mLoading) {
            showLoadingTips();
        } else {
            if (s.toString().getBytes().length == s.toString().length())
                isCnOrEn = false;
            else
                isCnOrEn = true;
            if (isCnOrEn) {
                mAdapterCte = new WordAdapterCte(HomeScreen.this);
                mListView.setAdapter(mAdapterCte);
                getWordSuggestCte(s);
            } else {
                mAdapter = new WordAdapter(HomeScreen.this);
                mListView.setAdapter(mAdapter);
                getWordSuggest(s);
            }
        }
    }

    /* ======================= menu ======================== */

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, Menu.FIRST + 1, Menu.NONE, R.string.history).setIcon(
                android.R.drawable.ic_menu_directions);
        menu.add(0, Menu.FIRST + 2, Menu.NONE, R.string.newwords).setIcon(
                android.R.drawable.ic_menu_always_landscape_portrait);
        // menu.add(0, Menu.FIRST + 3, Menu.NONE, R.string.setting).setIcon(
        // android.R.drawable.ic_menu_set_as);
        return true;
    }

    Intent menuIntent = new Intent();

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);
        switch (item.getItemId()) {

            case Menu.FIRST + 1:
                menuIntent.setClass(this, HistoryScreen.class);
                startActivity(menuIntent);
                break;

            case Menu.FIRST + 2:
                menuIntent.setClass(this, NewWordsScreen.class);
                startActivity(menuIntent);
                break;
            // case Menu.FIRST + 3:
            // dialog = new AlertDialog.Builder(this).setIcon(
            // android.R.drawable.ic_dialog_dialer)
            // .setTitle("加载同时是否提示声明?").setPositiveButton("是",
            // new DialogInterface.OnClickListener() {
            // public void onClick(DialogInterface dialog,
            // int whichButton) {
            // mShareUtil.ok();
            // }
            // }).setNegativeButton("否",
            // new DialogInterface.OnClickListener() {
            // public void onClick(DialogInterface dialog,
            // int whichButton) {
            // mShareUtil.cancle();
            // }
            // }).create();
            // dialog.show();
            // break;
        }

        return true;

    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        super.onKeyDown(keyCode, event);

        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {

            dialog = new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_menu_more)
                    .setTitle(R.string._exit_message).setPositiveButton(R.string._ok,
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int whichButton) {
                                    finish();
                                }
                            }).setNegativeButton(R.string._cancle,
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int whichButton) {
                                }
                            }).create();
            dialog.show();
        }
        return super.onKeyDown(keyCode, event);
    }
}
